#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include "base.h"
#include "my_serialize.h"

#define SIZE_BUF 256

void test_serialize_filename(){
    {
        struct C2S_filename request_info;
        request_info.type = 1;
        strcpy(request_info.filename,"./test.txt");
        char buffer[SIZE_BUF] = {0};

        char expect_buffer[SIZE_BUF] = {0};
        int offset = serialize_int(expect_buffer,0,request_info.type);
        serialize_string(expect_buffer,offset,request_info.filename);

        int ret = serialize_filename(buffer,&request_info);
        int expect_ret = sizeof(request_info.type)+sizeof(int)+strlen(request_info.filename)+1;
        if(ret != expect_ret || memcmp(buffer,expect_buffer,SIZE_BUF) != 0){
            printf("1 serialize_filename has err\n");
        }
        else {
            printf("1 serialize_filename no err\n");
        }
    }
    {
        struct C2S_filename request_info;
        request_info.type = 1;
        strcpy(request_info.filename,"./test.txt");
        char* buffer = NULL;

        char* expect_buffer = NULL;

        int ret = serialize_filename(buffer,&request_info);
        int expect_ret = -1;
        if(ret != expect_ret || buffer != expect_buffer){
            printf("2 serialize_filename has err\n");
        }
        else {
            printf("2 serialize_filename no err\n");
        }
    }
}

void test_unserialize_filename(){
    {
        struct C2S_filename data;
        data.type = 1;
        strcpy(data.filename,"aaa.txt");

        struct C2S_filename expect_data;
        memset(&expect_data,0,sizeof(expect_data));
        expect_data.type = 1;
        strcpy(expect_data.filename,"aaa.txt");
        char buffer[SIZE_BUF] = {0};
        serialize_filename(buffer,&data);
        int expect_ret = 0;
        memset(&data,0,sizeof(data));
        int ret = unserialize_filename(&data,buffer); 
        data.type = 1;
        if(ret != expect_ret || memcmp(&data,&expect_data,sizeof(data)) != 0){
            printf("1 unserialize_filename has err\n");
            printf("%d %d\n",data.type,expect_data.type);
        }
        else {
            printf("1 unserialize_filename no err\n");
        }
    }
    {
        struct C2S_filename data;
        data.type = 1;
        strcpy(data.filename,"aaa.txt");
        struct C2S_filename expect_data;
        expect_data.type = 1;
        strcpy(expect_data.filename,"aaa.txt");
        char buffer[SIZE_BUF] = {0};
        serialize_filename(buffer,&data);
        int expect_ret = -1;
        int ret = unserialize_filename(&data,NULL);
        if(ret != expect_ret || memcmp(&data,&expect_data,sizeof(data)) != 0){
            printf("2 unserialize_filename has err\n");
        }
        else {
            printf("2 unserialize_filename no err\n");
        }
    }
}

void test_serialize_fileinfo(){
    {
        struct S2C_fileinfo data;
        data.type = S2C_FILEINFO;
        data.size = 54678976;
        char buffer[SIZE_BUF] = {0};
        char expect_buffer[SIZE_BUF] = {0};
        int offset = serialize_int(expect_buffer,0,data.type);
        int expect_ret = serialize_uint64_t(expect_buffer,offset,data.size);
        int ret = serialize_fileinfo(buffer,&data);
        if(ret != expect_ret || memcmp(buffer,expect_buffer,SIZE_BUF) != 0){
            printf("1 serialize_fileinfo has err\n");
        }
        else {
            printf("1 serialize_fileinfo no err\n");
        }
    }
}

void test_unserialize_fileinfo(){
    {
        struct S2C_fileinfo data;
        data.type = S2C_FILEINFO;
        data.size = 54678976;

        struct S2C_fileinfo expect_data;
        memset(&expect_data,0,sizeof(expect_data));
        expect_data.type = S2C_FILEINFO;
        expect_data.size = 54678976;
        int expect_ret = 0;
        char buffer[SIZE_BUF] = {0};
        serialize_fileinfo(buffer,&data);
        memset(&data,0,sizeof(data));
        int ret = unserialize_fileinfo(&data,buffer);

        if(ret != expect_ret || expect_data.size != data.size){
            printf("1 unserialize_fileinfo has err\n");
        }
        else {
            printf("1 unserialize_fileinfo no err\n");
        }
    }
}

void test_serialize_loadinfo(){
    {
        struct C2S_loadinfo data;
        data.type = C2S_LOADINFO;
        strcpy(data.filepath,"test.txt");
        data.offset = 543654;
        data.block_size = 1024;
        char expect_buffer[SIZE_BUF] = {0};
        int offset = serialize_int(expect_buffer,0,data.type);
        offset = serialize_string(expect_buffer,offset,data.filepath);
        offset = serialize_uint64_t(expect_buffer,offset,data.offset);
        int expect_ret = serialize_uint64_t(expect_buffer,offset,data.block_size);
        char buffer[SIZE_BUF] = {0};
        int ret = serialize_loadinfo(buffer,&data);
        if(ret != expect_ret || memcmp(buffer,expect_buffer,SIZE_BUF) != 0){
            printf("1 serialize_loadinfo has err\n");
        }
        else {
            printf("1 serialize_loadinfo no err\n");
        }
    }
}

void test_unserialize_loadinfo(){
    {
        struct C2S_loadinfo data;
        data.type = C2S_LOADINFO;
        strcpy(data.filepath,"test.txt");
        data.offset = 543654;
        data.block_size = 1024;
        struct C2S_loadinfo expect_data;
        expect_data.type = C2S_LOADINFO;
        strcpy(expect_data.filepath,"test.txt");
        expect_data.offset = 543654;
        expect_data.block_size = 1024;
        int expect_ret = 0;

        char buffer[SIZE_BUF] = {0};
        serialize_loadinfo(buffer,&data);
        memset(&data,0,sizeof(data));
        int ret = unserialize_loadinfo(&data,buffer);
        if(ret != expect_ret || memcmp(&data,&expect_data,sizeof(data)) != 0){
            printf("1 unserialize_loadinfo has err\n");
        }
        else {
            printf("1 unserialize_loadinfo no err\n");
        }
    }
}

void test_serialize_fileblock(){
    {
        struct S2C_file_block data;
        data.type = S2C_FILEBLOCK;
        data.offset = 0x1234578;
        memset(data.content,1,BLOCK_SIZE);
        char expect_buffer[SIZE_BUF] = {0};
        int offset = serialize_int(expect_buffer,0,data.type);
        offset = serialize_uint64_t(expect_buffer,offset,data.offset);
        int expect_ret = serialize_arr_ch(expect_buffer,offset,data.content,BLOCK_SIZE);
        char buffer[SIZE_BUF] = {0};
        int ret = serialize_fileblock(buffer,&data,BLOCK_SIZE);
        if(ret != expect_ret || memcmp(buffer,expect_buffer,SIZE_BUF) != 0){
            printf("1 serialize_fileblock has err\n");
        }
        else {
            printf("1 serialize_fileblock no err\n");
        }
    }
}

void test_unserialize_fileblock(){
    struct S2C_file_block data;
    data.type = S2C_FILEBLOCK;
    data.offset = 0x1234578;
    memset(data.content,1,BLOCK_SIZE);
    struct S2C_file_block expect_data;
    expect_data.type = S2C_FILEBLOCK;
    expect_data.offset = 0x1234578;
    memset(expect_data.content,1,BLOCK_SIZE);
    char buffer[SIZE_BUF] = {0};
    serialize_fileblock(buffer,&data,BLOCK_SIZE);
    int expect_ret = BLOCK_SIZE;
    memset(&data,0,sizeof(data));
    int ret = unserialize_fileblock(&data,buffer);
    data.type = S2C_FILEBLOCK;
    if(ret != expect_ret || memcmp(&data,&expect_data,sizeof(data)) != 0){
        printf("1 unserialize_fileblock has err\n");
    }
    else {
        printf("1 unserialize_fileblock no err\n");
    }
}

void test_addlength(){
    {
        int size = 100;
        char* buffer = NULL;
        char* ret =  addlength(buffer,size);
        char* expect_ret = NULL;
        if(ret != expect_ret){
            printf("1 addlength has err\n");
        }
        else {
            printf("1 addlength no err\n");
        }
    }
    {
        int size = 1234;
        char buffer[64] = "abcd";
        char* ret = addlength(buffer,size);
        char expect_ret[68] = "";
        unsigned int tmp = htonl(size);
        memcpy(expect_ret,&tmp,sizeof(int));
        memcpy(expect_ret+sizeof(int),buffer,sizeof(buffer));
        if(memcmp(ret,expect_ret,68) != 0){
            printf("2 addlength has err\n");
        }
        else {
            printf("2 addlength no err\n");
        }
        free(ret);
        ret = NULL;
    }
}

void test_recv_header(){
    {
        int data = -1;
        int expect_ret = -1;
        int ret = recv_header(data);
        if(ret != expect_ret){
            printf("1 recv_header has err\n");
        }
        else {
            printf("1 recv_header no err\n");
        }
    }
}

int main(int argc, char const *argv[])
{
    test_serialize_filename();
    test_unserialize_filename();
    test_serialize_fileinfo();
    test_unserialize_fileinfo();
    test_serialize_loadinfo();
    test_unserialize_loadinfo();
    test_serialize_fileblock();
    test_unserialize_fileblock();
    test_addlength();
    test_recv_header();
    return 0;
}
